/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.silverfoxserver.ext.handler;


import System.Xml.XmlDocument;
import System.Xml.XmlHelper;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.silverfoxserver.core.array.QueueMethod;
import net.silverfoxserver.core.log.Log;
import net.silverfoxserver.core.protocol.ClientAction;
import net.silverfoxserver.core.service.IoHandler;
import net.silverfoxserver.core.socket.SessionMessage;
import net.silverfoxserver.core.socket.SocketConnector;
import net.silverfoxserver.core.socket.XmlInstruction;
import net.silverfoxserver.core.util.SHA1ByAdobe;
import net.silverfoxserver.ext.Globals;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.handler.ssl.SslHandler;
import org.jdom2.Attribute;
import org.jdom2.Element;
import org.jdom2.JDOMException;

/**
 *
 * @author ACER-FX
 */
public class GameClientHandler implements IoHandler{
    
    //static final ChannelGroup channels = new DefaultChannelGroup();

    /**
     * 记录CLIENT与游戏逻辑服务之间的对应关系
     * 在断线时进行通知
     */
    static final ConcurrentHashMap _serverMapList = new ConcurrentHashMap();
    
    public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e){
        if (e instanceof ChannelStateEvent) {
            System.err.println(e);
        }
        //super.handleUpstream(ctx, e);
    }
    
    public void sessionCreated(ChannelHandlerContext ctx, ChannelStateEvent e) {
        // Get the SslHandler in the current pipeline.
        // We added it in SecureChatPipelineFactory.
        //final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);

        // Get notified when SSL handshake is done.
       // ChannelFuture handshakeFuture = sslHandler.handshake();
        //handshakeFuture.addListener(new Greeter(sslHandler));
    }
    
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
        // Unregister the channel from the global channel list
        // so the channel does not receive messages anymore.
        //channels.remove(e.getChannel());
    }
    
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e,XmlDocument d) {

       
        MessageEvent s = e;        
        
        XmlDocument doc = d;//new XmlDocument();
        //doc.LoadXml((String)message);
        
        Attribute serverAtt = doc.getDocumentElement().getChildren().get(0).getAttribute("server");
        Attribute gateAtt   = doc.getDocumentElement().getChildren().get(0).getAttribute("gate");
        Attribute sAtt = doc.getDocumentElement().getChildren().get(0).getAttribute("s");
        
        if(null == sAtt)
        {
            Log.WriteStrByWarn("doc body element do not have s attribute: " + doc.toString());
            return;
        }
        
        if(null == serverAtt)
        {
            Log.WriteStrByWarn("doc body element do not have server attribute: " + doc.toString());
            return;
        }
        
        if(null == gateAtt)
        {
           //增加
            String gateName = Globals.mainWindowModel.acceptor.getServerName(); //Program.GAME_NAME    
            doc.getDocumentElement().getChildren().get(0).setAttribute("gate", gateName);
        }

        String serverNickName = serverAtt.getValue();
        
        //
        InetSocketAddress remoteAddress = (InetSocketAddress)e.getChannel().getRemoteAddress();
        String strIpPort = remoteAddress.getAddress().getHostAddress() + ":" + String.valueOf(remoteAddress.getPort());

        _serverMapList.put(strIpPort, serverNickName);
        
        
        
        //session
        doc.getDocumentElement().getChildren().get(0).getAttribute("s").setValue(strIpPort);
        
        
                      
        String msgOri = doc.toString();//(String)e.getMessage();
        
        msgOri += "\0";
        
        //转发原始数据给游戏逻辑服务
        SocketConnector ts = Globals.mainWindowModel.findConnectServer(serverNickName);
        ts.Write(msgOri.getBytes(Charset.forName("utf-8")));
        
       
    }
    
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getCause().printStackTrace();
        e.getChannel().close();
    }

    @Override
    public void sessionOpened() {
       //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void sessionClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
       
        
        try
        {
             Channel c = e.getChannel();
            
            InetSocketAddress remoteAddress = (InetSocketAddress)c.getRemoteAddress();
            String strIpPort = remoteAddress.getAddress().getHostAddress() + ":" + String.valueOf(remoteAddress.getPort());

            
           XmlDocument doc = new XmlDocument();
           doc.LoadXml(XmlInstruction.SysTemplate);
            
            doc.getBodyElement().setAttribute("action","sessionClosed");
            
            doc.getBodyElement().setAttribute("s",strIpPort);
            
            doc.getBodyElement().setAttribute("gate", Globals.mainWindowModel.acceptor.getServerName());
            
            String serverNickName = (String)_serverMapList.get(strIpPort);
            
            doc.getBodyElement().setAttribute("server",serverNickName);
            
            //
            String msgOri = doc.toString();
        
            msgOri += "\0";
        
            //转发原始数据给游戏逻辑服务
            
            SocketConnector ts = Globals.mainWindowModel.findConnectServer(serverNickName);
            ts.Write(msgOri.getBytes(Charset.forName("utf-8")));
           
            //
            _serverMapList.remove(strIpPort);

        }
        catch (JDOMException | IOException |RuntimeException exd)
        {
                Globals.out.WriteStrByException(GameClientHandler.class.getName(), "sessionClosed", exd.getMessage());
        } 
        /**/
    
    }
    
    
}
